#include "stdafx.h"
#include "ProjectWnd.h"
#include "Foundation.h"
#include "Renderer.h"
#include "Scene.h"
#include "worldSceneControl.h"

CProjectWnd* gProjectWnd = nullptr;
std::string	currentDir = "";
static mini::ui::CWnd* gWnd = nullptr;

void bindRenderTarget(mini::ui::CWnd* pWnd, mini::ui::CList::listItem* pItemList)
{
	mini::ui::GuiStyle* pGuiStyle = nullptr;
	if (nullptr != gWnd)
	{
		pGuiStyle = gWnd->getGuiStyle();
		pGuiStyle->mTextures[0]->saveToFile(pGuiStyle->getResourceName());
		auto pTexture = dynamic_cast<mini::CTexture*>
			(mini::GEngine->createResource(pGuiStyle->getResourceName(),
				mini::ResType::Texture));
		if (nullptr != pTexture)
		{
			pGuiStyle->mTextures[0] = pTexture;
			gWnd->unBindRenderViewport();
		}
	}
	auto fileName = mini::foundation::splitString<std::string>(pItemList->mText, ".");
	auto tempActorName = fileName[1];
	std::transform(tempActorName.begin(), tempActorName.end(), tempActorName.begin(), ::tolower);
	mini::EntityType type = mini::EntityType::Actor;

	auto tempFileName = currentDir + "Temp/" + fileName[0] + ".png";
	auto pTexture = dynamic_cast<mini::CTexture*>
		(mini::CResourceManager::getSinglePtr()->createResource(tempFileName,
			mini::ResType::Texture));

	pGuiStyle = nullptr;

	tempActorName = currentDir + pItemList->mText;
	auto tempMaterialName = currentDir + "../Material/" + fileName[0] + ".ma";
	std::transform(tempActorName.begin(), tempActorName.end(), tempActorName.begin(), ::tolower);

	auto item = gProjectWnd->mLoadActos.find(tempActorName);
	mini::CRenderNode*  pRenderNode = nullptr;
	mini::CActor* pActor = nullptr;
	if (gProjectWnd->mLoadActos.end() == item)
	{
		pRenderNode = mini::GEngine->createRenderNode();
		pActor = mini::GEngine->createActor(tempActorName,
			tempMaterialName,
			type);
		pRenderNode->bindActor(pActor, mini::RendererType::FrontRenderer);
	}
	else
	{
		pActor = (item->second).mpActor;
		pRenderNode = mini::GEngine->getCurrentScene()->getRenderNodeByActor(pActor);
	}
	gProjectWnd->mpChooseActor = pActor;
	pActor->AddRef();
	pWnd->bindRenderViewport(gProjectWnd->mpRenderViewport);
	pGuiStyle = pWnd->getGuiStyle();

	auto pInfo = gProjectWnd->mpRenderViewport->addRenderNode(pRenderNode);
	gProjectWnd->mpRenderViewport->enable();
	previewActor info;
	info.mpActor = pActor;
	info.mpActorPlaceInfo = pInfo;
	gProjectWnd->mLoadActos[tempActorName] = info;
	pGuiStyle->setResourceName(tempFileName);
	gWnd = pWnd;
}

void changeScene(mini::ui::CList::listItem* pItemList)
{
	auto fileName = mini::foundation::splitString<std::string>(pItemList->mText, ".");
	auto tempActorName = fileName[1];
	std::transform(tempActorName.begin(), tempActorName.end(), tempActorName.begin(), ::tolower);
	mini::GEngine->stopRender();
	mini::CScene* pWorldScne = mini::GEngine->loadScene(fileName[0]);
	CWorldSceneControl* pSceneControl = new CWorldSceneControl;
	pWorldScne->addSceneControl(pSceneControl);
	mini::GEngine->recoverRender();
}

void runSelectItem(bool bDoubleClick, mini::ui::CList::listItem* pItemList)
{
	if (nullptr == pItemList)
	{
		if (nullptr != gWnd)
		{
			auto pGuiStyle = gWnd->getGuiStyle();
			pGuiStyle->mTextures[0]->saveToFile(pGuiStyle->getResourceName());
			auto pTexture = dynamic_cast<mini::CTexture*>
				(mini::GEngine->createResource(pGuiStyle->getResourceName(),
					mini::ResType::Texture));
			pGuiStyle->mTextures[0] = pTexture;
			gWnd->setGuiStyle(pGuiStyle);
			gWnd = nullptr;
			gProjectWnd->mpRenderViewport->disable();
		}
	}
	else
	{
		int nIndex = 0;
		mini::ui::CWnd* pWnd = pItemList->mpWnd->getChildWnd(nIndex);
		while (nullptr != pWnd)
		{
			if (pWnd->getWndType() == mini::ui::ui_image)
			{
				auto fileName = mini::foundation::splitString<std::string>(pItemList->mText, ".");
				auto tempActorName = fileName[1];
				std::transform(tempActorName.begin(), tempActorName.end(), tempActorName.begin(), ::tolower);
				if ("fbx" == tempActorName)
				{
					bindRenderTarget(pWnd, pItemList);
				}
				else if ("xml" == tempActorName && bDoubleClick)
				{
					changeScene(pItemList);
				}
				break;
			} 
			else
			{
				pWnd = pItemList->mpWnd->getChildWnd(++nIndex);
			}
		}
	}
}

void mouseMove(int x, int y)
{
	static int old_x = -1;
	static int old_y = -1;
	if ((GetKeyState(VK_LBUTTON) & 0x8000) != 0)
	{
		if (-1 == old_x && -1 == old_y)
		{
			old_x = x;
			old_y = y;
		}
		else
		{

			float offsetX = x - old_x;
			float offsetY = y - old_y;
			auto rotation = gProjectWnd->mpChooseActor->getRotation();
			rotation.x += offsetX;
			rotation.y += offsetY;
			gProjectWnd->mpChooseActor->setRotation(rotation, true);
			old_x = x;
			old_y = y;
		}
	}
	else
	{
		old_x = -1;
		old_y = -1;
	}

}


void whellControl(int iMessage)
{
	if (nullptr != gProjectWnd->mpChooseActor)
	{
		for (auto item : gProjectWnd->mLoadActos)
		{
			if (gProjectWnd->mpChooseActor == (item.second).mpActor)
			{
				if (mini::MSG_TYPE::MOUSEWHEELDOWN == iMessage)
				{
					(item.second).mpActorPlaceInfo->point.z += 1;
				}
				else if (mini::MSG_TYPE::MOUSEWHEELUP == iMessage)
				{
					(item.second).mpActorPlaceInfo->point.z += 2;
				}
			}
		}
		
	}
}

void updateFileInfo(mini::ui::CList* pList, mini::ui::CList::listItem* pItemList)
{
	if (nullptr != pItemList &&
		nullptr != pItemList->mpWnd)
	{
		if (pItemList->mbUpdate)
		{
			if (pItemList->mbDrop)
			{
				std::string strDir = "";
				auto pTempListItem = pItemList->mParentListItem;
				while (pTempListItem != nullptr)
				{
					strDir = pTempListItem->mText + "/" + strDir;
					pTempListItem = pTempListItem->mParentListItem;
				}
				strDir = "Resource/" + strDir + pItemList->mText;
				auto&& info = mini::foundation::getFileInfoList(strDir.c_str());
				std::vector<std::string>& fileDir = std::get<0>(info);
				for (auto name : fileDir)
				{
					if (name != "Temp")
					{
						pList->addItem(pItemList, name);
					}
				}
			}
			else
			{
				pList->deleteAllItem(pItemList);
			}
		}
		else
		{
			std::string strDir = "";
			auto pTempListItem = pItemList->mParentListItem;
			while (pTempListItem != nullptr)
			{
				strDir = pTempListItem->mText + "/" + strDir;
				pTempListItem = pTempListItem->mParentListItem;
			}
			strDir = "Resource/" + strDir + pItemList->mText + "/";
			auto&& info = mini::foundation::getFileInfoList(strDir.c_str());
			std::vector<std::string>& fileName = std::get<1>(info);
			gProjectWnd->mpAssets->deleteAllItem();
			currentDir = strDir;
			for (auto name : fileName)
			{
				if (pItemList->mText == "Scene")
				{
					if (mini::foundation::getFileExtension(name) == "bmp")
					{
						continue;
					}
				}
				auto pListItem = gProjectWnd->mpAssets->addRootItem(name);
				std::string&& strExtension = mini::foundation::getFileExtension(name);
				if ("fbx" == strExtension)
				{
					int nIndex = 0;
					mini::ui::CWnd* pWnd = pListItem->mpWnd->getChildWnd(nIndex);
					while (nullptr != pWnd)
					{
						if (pWnd->getWndType() == mini::ui::ui_image)
						{
							std::string&& strFile = mini::foundation::getFile(name);
							auto tempFileName = strDir + "Temp/" + strFile + ".png";
							auto pTexture = dynamic_cast<mini::CTexture*>
								(mini::CResourceManager::getSinglePtr()->createResource(tempFileName,
									mini::ResType::Texture));
							if (nullptr != pTexture)
							{
								mini::ui::GuiStyle* pGuiStyle = nullptr;
								auto pStyle = pWnd->getGuiStyle();
								pGuiStyle = pStyle->clone();
								pGuiStyle->mTextures[0] = pTexture;
								pWnd->setGuiStyle(pGuiStyle);
								pGuiStyle->setResourceName(tempFileName);
							}
							break;
						}
						else
						{
							pWnd = pListItem->mpWnd->getChildWnd(++nIndex);
						}
					}
				}
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////////
CProjectWnd::CProjectWnd()
{
	gProjectWnd = this;
}

CProjectWnd::~CProjectWnd()
{
	SafeRelease(mpChooseActor);
}


void CProjectWnd::initWnd()
{
	mpAssetContent = dynamic_cast<mini::ui::CList*>(findChildWnd("AssetContent"));
	mpAssets = dynamic_cast<mini::ui::CList*>(findChildWnd("Assets"));
	if (nullptr != mpAssets)
	{
		mpAssets->setMode(mini::ui::CList::box);
		mpAssets->setSelectItemFunc(runSelectItem);
		mpAssets->setDoubleClickItemFunc(runSelectItem);
		
	}
	if (nullptr != mpAssetContent)
	{
		mpAssetContent->setMode(mini::ui::CList::tree);	
		mpAssetContent->setSelectContentFunc(updateFileInfo);
		mpAssets->setMouseWheelFunc(whellControl);
		mpAssets->setMouseMoveFunc(mouseMove);
	}

	auto&& info = mini::foundation::getFileInfoList("Resource");
	std::vector<std::string>& fileDir = std::get<0>(info);
	std::vector<std::string>& fileNames = std::get<1>(info);

	for (auto& item : fileDir)
	{
		mpAssetContent->addRootItem(item);
	}
	for (auto& item : fileNames)
	{
		mpAssets->addRootItem(item);
	}
	auto pRenderViewport = dynamic_cast<mini::CRenderViewport*>(mini::GEngine->createActor(mini::EntityType::RenderViewPort));
	mpRenderViewport = pRenderViewport;
	pRenderViewport->setName("modelPreviewViewport");
	pRenderViewport->createBuildCamera("previewCamera", mini::CPoint3F(0, 0, -10), mini::CPoint3F());
	pRenderViewport->initViewPortSize(mini::GEngine->getDeviceWidth(), mini::GEngine->getDeviceHeight());

	auto pScene = mini::GEngine->getCurrentScene();
	pScene->addActor(pRenderViewport);
	SafeRelease(pRenderViewport);
}
